package runtime

import (
	"encoding/json"
	"errors"
	"gopkg.in/yaml.v2"
	"time"
)

type Manifest struct {
	Pipe *Pipeline `json:"pipe"`
}

//此处对应的是pipeline_version表的数据
type Pipeline struct {
	Id          string              `json:"id"`
	BuildId     string              `json:"buildId"`
	Name        string              `yaml:"name" json:"name"`
	Version     string              `yaml:"version" json:"version"`
	DisplayName string              `yaml:"displayName" json:"displayName"`
	Triggers    map[string]*Trigger `yaml:"triggers" json:"triggers"`
	Variables   map[string]string   `yaml:"variables" json:"variables"`
	Stages      []*Stage            `yaml:"stages" json:"stages"`
}

type Build struct {
	Id        string                `json:"id"`
	Trigger   string                `json:"trigger"`
	Status    string                `json:"status"`
	Ref       string                `json:"ref"`
	Error     string                `json:"error,omitempty"`
	Event     string                `json:"event"`
	Timestamp time.Time             `json:"timestamp"`
	Title     string                `json:"title,omitempty"`
	Message   string                `json:"message"`
	Vars      map[string]*Variables `json:"vars"`
	Started   time.Time             `json:"started"`
	Finished  time.Time             `json:"finished"`
	Created   time.Time             `json:"created"`
	Updated   time.Time             `json:"updated"`
	Before    string                `json:"before"`
	After     string                `json:"after"`
	Version   string                `json:"version"`
	THookId   string                `json:"tHookId"`
	Cfg       *Manifest             `json:"manifest"`
}
type Variables struct {
	Name   string `yaml:"name,omitempty" json:"name"`
	Value  string `yaml:"value,omitempty" json:"value"`
	Secret bool   `yaml:"secret,omitempty" json:"secret"`
}

type Trigger struct {
	AutoCancel     bool           `json:"autoCancel"`
	Timeout        string         `json:"timeout"`
	Branches       *Branch        `json:"branches"`
	Tags           *Tag           `json:"tags"`
	Paths          *Path          `json:"paths"`
	CommitMessages *CommitMessage `json:"commitMessages"`
}
type CommitMessage struct {
	Include []string `json:"include"`
	Exclude []string `json:"exclude"`
}
type Path struct {
	Include []string `json:"include"`
	Exclude []string `json:"exclude"`
}
type Tag struct {
	Include []string `json:"include"`
	Exclude []string `json:"exclude"`
}
type Branch struct {
	Include []string `json:"include"`
	Exclude []string `json:"exclude"`
}
type Stage struct {
	Id          string            `json:"id"`
	PipelineId  string            `json:"pipelineId"`
	BuildId     string            `json:"buildId"`
	Name        string            `yaml:"name" json:"name"`
	DisplayName string            `yaml:"displayName" json:"displayName"`
	Stage       string            `yaml:"stage" json:"stage"`
	Status      string            `json:"status"`
	Error       string            `json:"error"`
	ExitCode    int               `json:"exit_code"`
	Started     time.Time         `json:"started"`
	Stopped     time.Time         `json:"stopped"`
	Finished    time.Time         `json:"finished"`
	Created     time.Time         `json:"created"`
	Updated     time.Time         `json:"updated"`
	Version     string            `json:"version"`
	OnSuccess   bool              `json:"on_success"`
	OnFailure   bool              `json:"on_failure"`
	Labels      map[string]string `json:"labels,omitempty"`
	Jobs        []*Job            `yaml:"jobs" json:"jobs"`
}

type Job struct {
	Id              string            `json:"id"`
	StageId         string            `json:"stageId"`
	BuildId         string            `json:"buildId"`
	Job             string            `yaml:"job" json:"job"`
	DisplayName     string            `yaml:"displayName" json:"displayName"`
	Name            string            `yaml:"name" json:"name"`
	PlugVars        map[string]string `yaml:"vars" json:"vars"`
	Environments    map[string]string `yaml:"environments" json:"environments"`
	Commands        []interface{}     `yaml:"commands" json:"-"`
	Command         string            `json:"'command'"`
	Number          int               `json:"number"`
	Status          string            `json:"status"`
	Error           string            `json:"error,omitempty"`
	ErrIgnore       bool              `json:"errignore,omitempty"`
	ExitCode        int               `json:"exit_code"`
	Started         time.Time         `json:"started,omitempty"`
	Stopped         time.Time         `json:"stopped,omitempty"`
	Finished        time.Time         `json:"finished"`
	Version         string            `json:"version"`
	DependsOn       []string          `yaml:"dependsOn" json:"dependsOn"`
	Image           string            `yaml:"image" json:"image"`
	Artifacts       []*Artifact       `yaml:"artifacts" json:"artifacts"`
	DependArtifacts []*DependArtifact `yaml:"dependArtifacts" json:"dependArtifacts"`
	Plugined        bool              `yaml:"-" json:"plugined"`
}

type Artifact struct {
	Id        string
	BuildId   string    `json:"buildId"`
	StageId   string    `json:"stageId"`
	JobId     string    `json:"jobId"`
	BuildName string    `json:"buildName"`
	StageName string    `json:"stageName"`
	JobName   string    `json:"jobName"`
	Status    string    `json:"status"`
	Created   time.Time `json:"created"`
	Updated   time.Time `json:"updated"`

	Name  string `yaml:"name" json:"name"`
	Scope string `yaml:"scope" json:"scope"`
	Path  string `yaml:"path" json:"path"`

	Artifactory string `yaml:"artifactory" json:"artifactory"`
	Repository  string `yaml:"repository" json:"repository"`

	Value string `yaml:"value" json:"value"`
}

type DependArtifact struct {
	Id        string
	BuildId   string    `json:"buildId"`
	StageId   string    `json:"stageId"`
	JobId     string    `json:"jobId"`
	BuildName string    `json:"buildName"`
	StageName string    `json:"stageName"`
	JobName   string    `json:"jobName"`
	Status    string    `json:"status"`
	Created   time.Time `json:"created"`
	Updated   time.Time `json:"updated"`

	Name        string `json:"name"`
	Type        string `json:"type"`
	IsForce     bool   `json:"isForce"`
	Artifactory string `json:"artifactory"` // no use
	Repository  string `json:"repository"`
	Target      string `json:"target"`

	SourceStage string `json:"sourceStage"`
	SourceJob   string `json:"sourceStep"`

	Value string `json:"value"`
}

func (job *Job) CommandYmlToStruct() error {
	var command []interface{}
	err := yaml.Unmarshal([]byte(job.Command), &command)
	job.Commands = command
	return err
}

func ParseBuildJSON(v []byte) (*Build, error) {
	build := new(Build)
	if v != nil && len(v) > 0 {
		err := json.Unmarshal(v, build)
		if err != nil {
			return nil, errors.New("json pares err:" + err.Error())
		}
	}
	return build, nil
}
